package ru.osu.acm.testing.solutions;

import java.io.*;
import java.util.StringTokenizer;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Random;

/**
 * User: Aleksey
 * Date: 16.01.2009
 * Time: 1:51:36
 */
public class Task10 implements Runnable {
    private static BufferedReader br = null;
    private static PrintWriter pw = null;
    private static StringTokenizer st = new StringTokenizer("");

    private void nline() {
        try {
            st = new StringTokenizer(br.readLine());
        }
        catch (IOException e) {
            throw new RuntimeException("RuntimeException");
        }
    }

    private int ni() {
        while (!st.hasMoreTokens()) nline();
        return Integer.parseInt(st.nextToken());
    }

    private long nl() {
        while (!st.hasMoreTokens()) nline();
        return Long.parseLong(st.nextToken());
    }

    private double nd() {
        while (!st.hasMoreTokens()) nline();
        return Double.parseDouble(st.nextToken());
    }

    private String ns() {
        while (!st.hasMoreTokens()) nline();
        return st.nextToken();
    }

    private boolean checkUsed(HashSet<Integer> candidates, HashSet<Integer> used) {
        boolean result = false;
        for (int v : used) {
            boolean withAll = true;
            for (int w : candidates) {
                if (!m[v][w]) {
                    withAll = false;
                    break;
                }
            }
            if (withAll) {
                result = true;
                break;
            }
        }
        return result;
    }

    private void print() {
        if (max < compsub.size()) {
            max = compsub.size();
        }
    }

    private void extend(HashSet<Integer> candidates, HashSet<Integer> used) {
        while (!candidates.isEmpty() && !checkUsed(candidates, used)) {
            int v = candidates.iterator().next();
            compsub.add(v);

            HashSet<Integer> newCandidates = new HashSet<Integer>();
            HashSet<Integer> newUsed = new HashSet<Integer>();

            for (int w : candidates) {
                if (m[v][w]) {
                    newCandidates.add(w);
                }
            }
            for (int w : used) {
                if (m[v][w]) {
                    newUsed.add(w);
                }
            }
            if (newCandidates.isEmpty() && newUsed.isEmpty()) {
                print();
            }
            else {
                extend(newCandidates, newUsed);
            }

            compsub.remove(v);
            candidates.remove(v);
            used.add(v);
        }
    }

    boolean[][] m;
    int n;
    HashSet<Integer> compsub = new HashSet<Integer>();
    int max = -1;

    private void solve() {
        n = ni();

        m = new boolean[n][n];

        for (int i = 0; i < n; i++) {
            int c = ni();
            for (int j = 0; j < c; j++) {
                int x = ni();
                m[i][x] = true;
                m[x][i] = true;
            }
        }

        HashSet<Integer> newCandidates = new HashSet<Integer>();
        HashSet<Integer> newUsed = new HashSet<Integer>();

        for (int i = 0; i < n; i++) {
            newCandidates.add(i);
        }

        extend(newCandidates, newUsed);
        pw.println(max);
    }

    public void run() {
        solve();
        pw.close();
    }

    private static void generate(int k, int minn, int maxn) {
        try {
            PrintWriter pw = new PrintWriter("input" + k + ".txt");

            Random rand = new Random();
            int n = rand.nextInt(maxn - minn) + minn;
            pw.println(n);
            boolean[][] m = new boolean[n][n];

            for (int i = 0; i < n; i++) {
                for (int j = i; j < n; j++) {
                    if (i == j) {
                        m[i][j] = false;
                    }
                    else {
                        if (rand.nextInt(3) == 0) {
                            m[i][j] = false;
                            m[j][i] = false;
                        }
                        else {
                            m[i][j] = true;
                            m[j][i] = true;
                        }
                    }
                }
            }

            for (int i = 0; i < n; i++) {
                int cnt = 0;
                for (int j = 0; j < n; j++) {
                    if (m[i][j]) {
                        cnt++;
                    }
                }
                String s = "" + cnt;
                for (int j = 0; j < n; j++) {
                    if (m[i][j]) {
                        s += " " + j;
                    }
                }
                s = s.trim();
                pw.println(s);
            }

            pw.close();
        }
        catch (FileNotFoundException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        /*br = new BufferedReader(new InputStreamReader(System.in));
        pw = new PrintWriter(new OutputStreamWriter(System.out));*/

        try {
            br = new BufferedReader(new FileReader("clique.in"));
            pw = new PrintWriter("clique.out");
        }
        catch (FileNotFoundException e) {
            throw new RuntimeException("RuntimeException");
        }

        new Thread(new Task10()).start();

        /*for (int i = 0; i < 2; i++) {
            generate(i, 3, 5);
        }
        for (int i = 2; i < 5; i++) {
            generate(i, 5, 15);
        }
        for (int i = 5; i < 15; i++) {
            generate(i, 20, 50);
        }*/
    }
}